home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d21 / apicsamp.arc / WASHER.C < prev    next >
Text File  |  1989-02-24  |  12KB  |  370 lines

  1. /****************************************************************
  2. *
  3. *  Name:          WASHER
  4. *
  5. *  Function:      Emulate a washing machine control panel.
  6. *
  7. *  Shows how to:  1. construct complex menus (dialogues) including 
  8. *                    select, input, output, and inactive fields.
  9. *                 2. change field types dynamically.
  10. *                 3. implement "radio button" select fields.
  11. *                 4. use a timer object to measure time intervals.
  12. *                 5. use an objectq to wait for multiple events.
  13. *
  14. ****************************************************************/
  15.  
  16.  
  17. #include <stdio.h>
  18. #include "dvapi.h"
  19.  
  20. /* minimum API version required */
  21. #define required 0x201
  22.  
  23. /* possible values of the "temperature" variable */
  24. #define HOT  0
  25. #define WARM 1
  26. #define COLD 2
  27.  
  28. /* possible values of the "state" variable */
  29. #define IDLE            0
  30. #define WASHING         1
  31. #define FIRST_RINSE     2
  32. #define FIRST_SPIN      3
  33. #define FINAL_RINSE     4
  34. #define FINAL_SPIN      5
  35.  
  36. /* actual API version number */
  37. int     version;
  38.  
  39. /* object handles */
  40. ulong   winme,pan,win,kbd,tim,obj;
  41.  
  42. /* variables used when reading from the menu */
  43. char    *kptr,*kend,field,field1[3];
  44. int     klng,kstatus,fsize;
  45.  
  46. /* variables set according to menu input */
  47. int     wash_time,temperature,second_rinse,bell;
  48.  
  49. /* state related variables */
  50. int     state,indicator,done;
  51.  
  52. /* variables for saving the cursor position */
  53. int     row,col;
  54.  
  55. /* panel library filename in ASCIIZ string format */
  56. char     lib[] = "examples.plb\x00";
  57.  
  58. /* name of panel within panel library */
  59. char     name[] = "washer";
  60.  
  61. /* status of last pan_open and pan_apply operation */
  62. int     status;
  63.  
  64.  
  65. /**********************************************************************
  66. *  main  -  check for DESQview present and enable required extensions.
  67. ***********************************************************************/
  68.  
  69. main () {
  70.   /* initialize C interfaces and get API version number */
  71.   version = api_init();
  72.  
  73.   /* if DESQview is not running or version is too low, display a message */
  74.   if (version < required) {
  75.     printf ("This program requires DESQview version %d.02%d or later.\n",
  76.              required/256,required%256);
  77.     }
  78.  
  79.   /* tell DESQview what extensions to enable and start application */
  80.   else {
  81.     api_level (required);
  82.     program_body();
  83.     }
  84.  
  85.   /* disable C interfaces and return from program */
  86.   api_exit();
  87.   }
  88.  
  89.  
  90. /**********************************************************************
  91. *  program_body  -  initialize application and loop processing events.
  92. ***********************************************************************/
  93.  
  94. program_body () {
  95.   /* get task window handle and open objectq */
  96.   winme = win_me();
  97.   obq_open();
  98.  
  99.   /* create timer object */
  100.   tim = tim_new();
  101.  
  102.   /* create and open panel object, and associate it with panel library */
  103.   pan = pan_new();
  104.   status = pan_open (pan,lib,sizeof (lib));
  105.  
  106.   /* apply named panel, and return window & keyboard handles */
  107.   status = pan_apply (pan,winme,name,strlen (name),&win,&kbd);
  108.  
  109.   /* preselect "hot water".  Jump cursor to field 1.  Set "state" to idle */
  110.   radio_button (win,2,4,2);
  111.   fld_cursor (win,1);
  112.   change_state (IDLE,0);
  113.   done = 0;
  114.  
  115.   /* position menu, mark as displayable, and make topmost in application. */
  116.   win_top (win);
  117.  
  118.   /* loop until "done" becomes TRUE */
  119.   while (!done) {
  120.  
  121.     /* wait for input from any open object and return its handle */
  122.     obj = obq_read();
  123.  
  124.     /* determine which object it is and process accordingly */
  125.     if (obj == kbd)
  126.       process_menu_event();
  127.     else
  128.     if (obj == tim)
  129.       process_timer_event();    
  130.     };                          
  131.  
  132.   /* free all allocated objects and return */
  133.   key_free (kbd);
  134.   win_free (win);
  135.   pan_free (pan);
  136.   tim_free (tim);
  137.  
  138.   }
  139.  
  140.  
  141. /**********************************************************************
  142. *  process_menu_event  -  process data returned from the menu.
  143. ***********************************************************************/
  144.  
  145. process_menu_event () {
  146.   /* get menu data and determine what event caused data to be returned */
  147.   key_read (kbd,&kptr,&klng);
  148.   kstatus = key_status (kbd);   
  149.  
  150.   /* beep and return if anything but a field selection */
  151.   if (kstatus != 1) {           
  152.     api_sound (1000,5);
  153.     return;
  154.     };
  155.  
  156.   /* point just past returned data.  Save current cursor position. */
  157.   kend = kptr+klng;             
  158.   qry_cursor (win,&row,&col);   
  159.  
  160.   /* loop once for each field returned */
  161.   while (kptr < kend) {         
  162.  
  163.     /* get field # and length.  Log field info to task window. */
  164.     field = *kptr;
  165.     fsize = *(int *)(kptr+1);
  166.     win_printf (winme,"field = %d   length = %d   contents = ",field,fsize);
  167.     win_write (winme,kptr+3,fsize); 
  168.     win_printf (winme,"\n");
  169.  
  170.     /* dispatch based on field number */
  171.     switch (field) {            
  172.  
  173.       case 1: /* wash time changed */                   
  174.         /* copy returned data to string variable and zero terminate */
  175.         memcpy (field1,kptr+3,2);            
  176.         field1[2] = 0;               
  177.  
  178.         /* convert to integer, clip at zero, and set state to IDLE */
  179.         wash_time = atoi (field1);           
  180.         if (wash_time < 0)
  181.           wash_time = 0;
  182.         change_state (IDLE,0);       
  183.         break;                       
  184.  
  185.       case 2: /* Hot water selected -  Select field 2.  Deselect fields
  186.                  3 and 4.  Log temperature. */ 
  187.         radio_button (win,2,4,2);            
  188.         temperature = HOT;                   
  189.         break;                       
  190.  
  191.       case 3: /* Warm water selected - Select field 3.  Deselect fields
  192.                  2 and 4.  Log temperature. */                  
  193.         radio_button (win,2,4,3);            
  194.         temperature = WARM;          
  195.         break;                       
  196.  
  197.       case 4: /* Cold water selected - Select field 4.  Deselect fields
  198.                  2 and 3.  Log temperature. */
  199.         radio_button (win,2,4,4);            
  200.         temperature = COLD;          
  201.         break;
  202.  
  203.       case 5: /* Second rinse - if the field data is "Y", the field is
  204.                  selected.  Otherwise, the data will be "N". */
  205.         second_rinse = (*(kptr+3) == 'Y');
  206.         break;                          
  207.  
  208.       case 6: /* Beep when done - if the field data is "Y", the field is
  209.                  selected.  Otherwise, the data will be "N". */         
  210.         bell = (*(kptr+3) == 'Y');           
  211.         break;                       
  212.  
  213.       case 7: /* Start button */
  214.         /* deselect field so it does not remain highlighted */
  215.         fld_type (win,7,FLT_DESELECT);  
  216.  
  217.         /* ignore if no wash time has been selected.  Otherwise ... */
  218.         if (wash_time != 0) {        
  219.  
  220.           /* convert field 1 to an output field.  Disable the start button
  221.              and enable the stop button */
  222.           fld_type (win,1,FLT_OUTPUT);
  223.           fld_type (win,7,FLT_INACTIVE); 
  224.           fld_type (win,8,FLT_DESELECT); 
  225.  
  226.           /* set timer to run 1 second.  If IDLE, set state to WASHING. */
  227.           tim_addto (tim,100L);      
  228.           if (state == IDLE)         
  229.             change_state (WASHING,10);
  230.           }
  231.         break;                       
  232.  
  233.       case 8: /* Stop button - stop cycle and reset field types. */
  234.         stop_cycle();
  235.         break;                       
  236.  
  237.       case 9: /* Exit button - stop cycle, reset fields, and set "done". */
  238.         stop_cycle();
  239.         done = 1;
  240.         break;
  241.  
  242.       default: /* unknown field number - should never happen. */
  243.         win_printf (winme,"impossible!\n");
  244.       }
  245.  
  246.     /* bump pointer to next field and loop */
  247.     kptr += (fsize+3);          
  248.     }                           
  249.  
  250.   /* restore original cursor position */
  251.   win_cursor (win,row,col);     
  252.   }                             
  253.  
  254.  
  255. /**********************************************************************
  256. *  process_timer_event  -  process timer expiration
  257. ***********************************************************************/
  258.  
  259. process_timer_event () {
  260.   long time;                    
  261.  
  262.   /* read the timer object to clear the event */
  263.   time = tim_read(tim);         
  264.  
  265.   /* save cursor position.  Decrement time remaining and display. */
  266.   wash_time -= 1;               
  267.   qry_cursor (win,&row,&col);   
  268.   fld_cursor (win,1);           
  269.   win_printf (win,"%2d",wash_time);  
  270.  
  271.   /* if the clock has expired, dispatch based on current state.
  272.      In each case, switch to the next state and light the appropriate
  273.      indicator. */
  274.   if (wash_time == 0) {         
  275.     switch (state) {            
  276.       case WASHING:             
  277.         change_state ((second_rinse) ? FIRST_RINSE:FINAL_RINSE, 11);
  278.         break;
  279.       case FIRST_RINSE:         
  280.         change_state (FIRST_SPIN,12);
  281.         break;
  282.       case FIRST_SPIN:          
  283.         change_state (FINAL_RINSE,11);
  284.         break;
  285.       case FINAL_RINSE:         
  286.         change_state (FINAL_SPIN,12);
  287.         break;
  288.       case FINAL_SPIN: /* Cycle complete - switch to IDLE state, beep if
  289.                           requested.  Restore original field types. */
  290.         change_state (IDLE,0);
  291.         if (bell == 1) api_sound (2000,18);
  292.         stop_cycle();
  293.         break;                          
  294.       }
  295.  
  296.     /* unless we are now IDLE, we need to start a rinse or spin cycle.
  297.        do so by setting the clock to 3 seconds and setting the timer to
  298.        expire in 1 second. */
  299.     if (state != IDLE) {                
  300.       wash_time = 3;            
  301.       tim_addto (tim,100L);     
  302.       }
  303.     }
  304.  
  305.   /* if clock is still counting, simply set timer for another second */
  306.   else                          
  307.     tim_addto (tim,100L);       
  308.  
  309.   /* restore cursor to its original position */
  310.   win_cursor (win,row,col);     
  311.   }
  312.  
  313.  
  314. /**********************************************************************
  315. *  radio_button  -  select a specified field and deselect all others in 
  316. *                   the given range.
  317. ***********************************************************************/
  318.  
  319. radio_button (win,first,last,chosen) ulong win; int first,last,chosen; {
  320.   int i;
  321.  
  322.   /* loop for each field in range "first" through "last" */
  323.   for (i=first; i<=last; i++)
  324.  
  325.     /* change "chosen" field type to SELECTed, others to DESELECTed */
  326.     fld_type (win,i,(i==chosen) ? FLT_SELECT : FLT_DESELECT);
  327.   }
  328.  
  329.  
  330. /**********************************************************************
  331. *  change_state  -  changes the current state of the wash cycle and 
  332. *                   lights the specified indicator.  The previously
  333. *                   lighted indicator, if any, is turned off.
  334. ***********************************************************************/
  335.  
  336. change_state (newstate,field) int newstate,field; {
  337.   /* log new state */
  338.   state = newstate;
  339.  
  340.   /* if an indicator is ON, turn it OFF */
  341.   if (indicator != 0) fld_attr (win,indicator,1);
  342.  
  343.   /* turn ON the requested indicator and remember it */
  344.   if (field != 0)     fld_attr (win,field,5);
  345.   indicator = field;
  346.   }
  347.  
  348.  
  349. /**********************************************************************
  350. *  stop_cycle  -  stops the current timer, if any.  Changes field 1 back
  351. *                 to an input field, enables the start button, and 
  352. *                 disables the stop button.
  353. ***********************************************************************/
  354.  
  355. stop_cycle () {
  356.   tim_erase (tim);                   
  357.   fld_type (win,1,FLT_INPUT);     
  358.   fld_type (win,7,FLT_DESELECT);  
  359.   fld_type (win,8,FLT_INACTIVE);  
  360.   }  
  361.  
  362.  
  363.  
  364.  
  365.  
  366.  
  367.  
  368.  
  369.  
  370.